import math

import function

from function import _Gamma as gamma
from function import _GetSpin as get_spin
from function import Spin

def breit_wigner(x, x1, x2, pdg_mass, pdg_width, l_decay):
    '''
    Return the value of a Breit-Wigner distribution at the given arguments.

    x  -- independent variable; either a physics.vector.Vector4 or a float
    x1 -- argument describing the first child of the decay of `x'; either physics.vector.Vector4 or a float
    x2 -- argument describing the second child of the decay of `x'; either physics.vector.Vector4 or a float
    pdg_mass -- the PDG mass of `x'
    pdg_width -- the PDG width of `x'
    l_decay -- the orbital angular momentum between x1 and x2    
    '''
    return function._BreitWigner(x, x1, x2, float(pdg_mass), float(pdg_width), int(l_decay))

def get_valid_ls(parent_spin, parent_parity,
                 decay1_spin, decay1_parity,
                 decay2_spin, decay2_parity):
    '''Get parity-conserving combinations of orbital and instrinsic angular momentum for a two-body decay.'''
    return function._GetValidLS(Spin(parent_spin), int(parent_parity),
                                    Spin(decay1_spin), int(decay1_parity),
                                    Spin(decay2_spin), int(decay2_parity))

def clebsch(s1, m1, s2, m2, J, M):
    '''Get the Clebsch-Gordan coefficient for the coupling between two states s1 and s2 
    with z-projections m1 and m2 into a state of total spin J with z-projection M.'''
    return function._Clebsch(Spin(s1), Spin(m1), Spin(s2), Spin(m2), Spin(J), Spin(M))

def wigner_d(j, m, n, beta):
    '''Return the value of the Wigner little-d function for the supplied arguments.'''
    return function._Wigner_d(Spin(j), Spin(m), Spin(n), float(beta))

def wigner_D(alpha, beta, gamma, j, m, n):
    '''Return the value of the Wigner little-d function for the supplied arguments.'''
    return function._Wigner_D(float(alpha), float(beta), float(gamma), 
                              Spin(j), Spin(m), Spin(n))

def regge_propogator(t, s, a, b, spin, sig, exp_fact):
    '''Return the value of the Regge propogator for the supplied arguments.'''
    return function._ReggePropogator(float(t), float(s), float(a), float(b), Spin(spin),
                                     int(sig), int(exp_fact))

def blatt_weisskopf(l, p):
    return function._BlattWeisskopf(Spin(l), p)

def cm_momentum(M, m1, m2):
    num = math.sqrt((M**2 - (m1+m2)**2)*(M**2 - (m1-m2)**2))

    return num/(2*M)

